/**
 * PNota.java
 * Copyright (C) 2009 Jose Mauro da Silva Sandy
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 */

package persistencia.notas;

import java.io.IOException;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import negocio.notas.Nota;
import plagio.postgres.ConnectionPostgres;
import utils.ConnectionSystem;
import utils.Log;
import utils.RedirectStackTrace;

/**
 *
 * @author jmsandy
 */
public class PNota {

    //<editor-fold defaultstate="collapsed" desc="Attributes">
    private boolean error = false;
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Acessores">
    public boolean isError(){
        return this.error;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Table Columns">
    static final protected String K_TBL_Nota           = "Nota";
    static final protected String K_COL_cod_objeto     = "cod_objeto";
    static final protected String K_COL_classname      = "classname";
    static final protected String K_COL_numNota        = "numnota";
    static final protected String K_COL_serie          = "serie";
    static final protected String K_COL_dtEmissao      = "dtemissao";
    static final protected String K_COL_dtEntrada      = "dtentrada";
    static final protected String K_COL_valorNota      = "valornota";
    static final protected String K_COL_situacao       = "situacao";
    static final protected String K_COL_fornecedor     = "fornecedor";
    static final protected String K_COL_empreendimento = "empreendimento";
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Constructor">
    /**
     * Construtor padrao. Responsavel por realizar a persistencia de uma Nota
     * @throws java.io.IOException
     */
    public PNota() throws IOException{
        error = false;
    }
    //</editor-fold>

    //<editor-fold defaultstate="collapsed" desc="Methods">
    // Realiza a construcao basica de um select
    private StringBuilder formSelector(){
        StringBuilder query = new StringBuilder();
        query.append("SELECT " + K_COL_cod_objeto + ", " + K_COL_classname);
        query.append(", " + K_COL_numNota + ", " + K_COL_serie + ", ");
        query.append(K_COL_dtEmissao + ", " + K_COL_dtEntrada + ", ");
        query.append(K_COL_valorNota + ", " + K_COL_situacao + ", ");
        query.append(K_COL_fornecedor + ", " + K_COL_empreendimento);
        query.append(" FROM \"" + K_TBL_Nota + "\"");
        return query;
    }

    /**
     * Responsavel por criar a estrutura para deletar o objeto
     * @param obj - Objeto a ser deletado na base de dados
     * @return construtor do objeto a ser deletado
     */
    protected String formDelete(Nota obj){
        return "DELETE FROM \"" + K_TBL_Nota + "\" WHERE " + K_COL_cod_objeto
                + " = '" + obj.getCod_objeto() + "'";
    }

    /**
     * Responsavel por deletar um objeto na base de dados
     * @param obj - objeto a ser deletado na base de dados
     * @return TRUE - caso afirmativo e FALSE - caso contrario
     */
    public Boolean delete(Nota obj){
        Boolean status = true;
        ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

        try{
            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            // Monta o objeto em uma instrucao SQL para atualizacao no banco
            PreparedStatement stat;
            String query = formDelete(obj);
            stat = conn.getConnection().prepareStatement(query);
            stat.executeUpdate();
            stat.close();
        }
        catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            status = false;
        }
        finally{
            conn.closeConnection();
        }
        return status;
    }

    /**
     * Verifica se existe uma nota para um dado empreendimento
     * @param idEmpreendimento identificador do empreendimento
     * @return TRUE se existe alguma nota e FALSE caso contrario
     */
    public Boolean existsEmp(String idEmpreendimento){
        Boolean ret = false;
        try{
            StringBuilder query = new StringBuilder();
            query.append("SELECT " + K_COL_cod_objeto + " FROM \"");
            query.append(K_TBL_Nota + "\" WHERE " + K_COL_empreendimento);
            query.append(" = '" + idEmpreendimento + "'");

            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();

            Statement stat = conn.getConnection().createStatement();
            ret = stat.executeQuery(query.toString()).next();
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
        }
        return ret;
    }

    /**
     * Verifica se existe uma nota para um dado fornecedor
     * @param idFornecedor identificador do fornecedor
     * @return TRUE se existe alguma nota e FALSE caso contrario
     */
    public Boolean existsForn(String idFornecedor){
        Boolean ret = false;
        try{
            StringBuilder query = new StringBuilder();
            query.append("SELECT " + K_COL_cod_objeto + " FROM \"");
            query.append(K_TBL_Nota + "\" WHERE " + K_COL_fornecedor);
            query.append(" = '" + idFornecedor + "'");

            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            Statement stat = conn.getConnection().createStatement();
            ret = stat.executeQuery(query.toString()).next();
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
        }
        return ret;
    }

    /**
     * Verifica se ja existe uma nota com o numero e serie informado para o
     * fornecedor selecionado
     * @param numNota numero da nota a ser procurada
     * @param serie serie da nota a ser procurada
     * @param idForn identificador do fornecedor vinculado a nota
     * @param idNota identificador da nota
     * @return retorna verdadeiro se ja existe a nota cadastrada para o
     * fornecedor em questao e falso caso contrario
     */
    public boolean exists(Integer numNota, String serie, String idForn,
                                                            String idNota){
        boolean exist = false;

        StringBuilder query = new StringBuilder();
        // Clausula where
        query.append("SELECT * FROM \"" + K_TBL_Nota + "\"");
        query.append(" WHERE " + K_COL_numNota + " = '" + numNota + "'");
        query.append(" AND " + K_COL_fornecedor + " = '" + idForn + "'");
        query.append(serie.length() > 0 ?
                    " AND " + K_COL_serie + " = '" + serie + "'" : "");

        // Verifica se e uma nota para edicao ou uma nova nota
        if(idNota != null && idNota.length() > 0){
            query.append(" AND " + K_COL_cod_objeto + " <> '" + idNota + "'");
        }

        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            Statement stat = conn.getConnection().createStatement();
            exist = stat.executeQuery(query.toString()).next();
        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            exist = false;
        }
        return exist;
    }

    /**
     * Recupera um objeto nota pelo codigo informado
     * @param idNota codigo da nota a ser procurada
     * @return a nota encontrada ou NULL
     */
    public Nota refresh(String idNota){
        Nota nota = new Nota(); // objeto de retorno

        StringBuilder query = this.formSelector();
        // Clausula wherecodigo do produto a ser procurado
        query.append(" WHERE " + K_COL_cod_objeto + " = '" + idNota + "'");
        try{
            ConnectionPostgres conn = new ConnectionPostgres(); // nova conexao

            // Realiza a conexao com o servidor
            conn = ConnectionSystem.connectionSystem();
            Statement stat = conn.getConnection().createStatement();

            // Verifica a existencia do registro de retorno
            ArrayList<Nota> lstNotas = new ArrayList<Nota>();
            lstNotas = mapear(stat.executeQuery(query.toString()));
            if(lstNotas.size() > 0) nota = lstNotas.get(0);
            else nota = null;

        }catch(Exception ex){
            Log.gravarLog(RedirectStackTrace.stackTraceToString(ex), this);
            error = true;
            nota = null;
        }
        return nota;
    }

    /**
     * Responsavel por converter o objeto vindo do banco de dados para um
     * modelo de objeto
     * @param result - result que obtem toda lista recebida do servidor
     * @return os objetos mapeados
     * @throws java.sql.SQLException
     */
    private ArrayList<Nota> mapear(ResultSet result) throws SQLException{
        ArrayList<Nota> lstNotas = new ArrayList<Nota>();

        // Converte todo result recebido para uma lista de objetos
        while(result.next()){
            Nota nota = new Nota();
            nota.setCod_objeto(result.getString(1));
            nota.setNumNota(result.getInt(3));
            nota.setSerie(result.getString(4));
            nota.setDtEmissao(result.getDate(5));
            nota.setDtEntrada(result.getDate(6));
            nota.setValorNota(result.getDouble(7));
            nota.setSituacao(result.getInt(8));
            nota.setFornecedor(result.getString(9));
            nota.setEmpreendimento(result.getString(10));

            nota.setIsNew(false);

            lstNotas.add(nota);
        }
        return lstNotas;
    }
    //</editor-fold>
}